﻿@page "/system/tenants"
@using CleanArchitecture.Blazor.Application.Features.Tenants.DTOs
@using CleanArchitecture.Blazor.Application.Features.Tenants.Queries.Pagination
@using CleanArchitecture.Blazor.Application.Features.Tenants.Caching
@using CleanArchitecture.Blazor.Application.Features.Tenants.Commands.AddEdit
@using CleanArchitecture.Blazor.Application.Features.Tenants.Commands.Delete

@attribute [Authorize(Policy = Permissions.Tenants.View)]
@inject IStringLocalizer<Tenants> L

<PageTitle>@Title</PageTitle>

<MudDataGrid ServerData="@(ServerReload)"
             FixedHeader="true"
             FixedFooter="false"
             Loading="@_loading"
             @bind-RowsPerPage="_defaultPageSize"
             MultiSelection="true"
             @bind-SelectedItems="_selectedItems"
             Hover="true" @ref="_tenantGrid">
    <ToolBarContent>
        <MudStack Row Spacing="0" Class="flex-grow-1" Justify="Justify.SpaceBetween">
            <!-- Left Toolbar: Icon and Title -->
            <MudStack Row AlignItems="AlignItems.Start">
                <MudIcon Icon="@Icons.Material.Filled.Domain" Size="Size.Large" />
                <MudStack Spacing="0">
                    <MudText Typo="Typo.subtitle2" Class="mb-2">@Title</MudText>
                </MudStack>
            </MudStack>
            <!-- Right Toolbar: Actions and Search -->
            <MudStack Spacing="0" AlignItems="AlignItems.End">
                <MudToolBar Dense WrapContent="true" Class="py-1 px-0">
                    <MudButton Disabled="@_loading"
                               OnClick="OnRefreshTenants"
                               StartIcon="@Icons.Material.Outlined.Refresh">
                        @ConstantString.Refresh
                    </MudButton>
                    @if (_accessRights.Create)
                    {
                        <MudButton StartIcon="@Icons.Material.Outlined.Add"
                                   OnClick="OnCreateTenant">
                            @ConstantString.New
                        </MudButton>
                    }
                    @if (_accessRights.Delete)
                    {
                        <MudButton StartIcon="@Icons.Material.Outlined.Delete"
                                   Disabled="@(!_selectedItems.Any())"
                                   OnClick="OnDeleteSelectedTenants">
                            @ConstantString.Delete
                        </MudButton>
                    }
                </MudToolBar>
                <MudStack Row Spacing="1">
                    @if (_accessRights.Search)
                    {
                        <MudTextField T="string"
                                      ValueChanged="OnSearchTenant"
                                      Value="@_tenantsQuery.Keyword"
                                      Placeholder="@ConstantString.Search"
                                      Adornment="Adornment.End"
                                      AdornmentIcon="@Icons.Material.Filled.Search"
                                      IconSize="Size.Small">
                        </MudTextField>
                    }
                </MudStack>
            </MudStack>
        </MudStack>
    </ToolBarContent>
    <Columns>
        <SelectColumn ShowInFooter="false"></SelectColumn>
        <TemplateColumn HeaderStyle="width:60px" Title="@ConstantString.Actions" Sortable="false">
            <CellTemplate>
                @if (_accessRights.Edit || _accessRights.Delete)
                {
                    <MudMenu Icon="@Icons.Material.Filled.Edit"
                             Variant="Variant.Filled"
                             Size="Size.Small"
                             Dense="true"
                             EndIcon="@Icons.Material.Filled.KeyboardArrowDown"
                             IconColor="Color.Info"
                             AnchorOrigin="Origin.CenterLeft">
                        @if (_accessRights.Edit)
                        {
                            <MudMenuItem OnClick="@(() => OnEditTenant(context.Item))">
                                @ConstantString.Edit
                            </MudMenuItem>
                        }
                        @if (_accessRights.Delete)
                        {
                            <MudMenuItem OnClick="@(() => OnDeleteTenant(context.Item))">
                                @ConstantString.Delete
                            </MudMenuItem>
                        }
                    </MudMenu>
                }
                else
                {
                    <MudButton Variant="Variant.Filled"
                               StartIcon="@Icons.Material.Filled.DoNotTouch"
                               IconColor="Color.Secondary"
                               Size="Size.Small"
                               Color="Color.Surface">
                        @ConstantString.NoAllowed
                    </MudButton>
                }
            </CellTemplate>
        </TemplateColumn>
        <PropertyColumn Property="x => x.Name" Title="@L[_currentDto.GetMemberDescription(x => x.Name)]">
            <FooterTemplate>
                @L["Selected"]: @_selectedItems.Count
            </FooterTemplate>
        </PropertyColumn>
        <PropertyColumn Property="x => x.Description" Title="@L[_currentDto.GetMemberDescription(x => x.Description)]">
            <CellTemplate>
                <div class="d-flex flex-column">
                    <MudText Typo="Typo.body2" Class="mud-text-secondary">
                        @context.Item.Description
                    </MudText>
                </div>
            </CellTemplate>
        </PropertyColumn>
    </Columns>
    <PagerContent>
        <MudDataGridPager PageSizeOptions="@(new[] { 10, 15, 30, 50, 100, 500, 1000 })" />
    </PagerContent>
</MudDataGrid>

@code {
    // Cascading parameters
    [CascadingParameter] private Task<AuthenticationState> AuthState { get; set; } = default!;

    // Public property for page title
    public string? Title { get; private set; }

    // Private fields
    private int _defaultPageSize = 15;
    private HashSet<TenantDto> _selectedItems = new();
    private MudDataGrid<TenantDto> _tenantGrid = default!;
    private TenantDto _currentDto = new();
    private TenantsAccessRights _accessRights = new();
    private string _searchString = string.Empty;
    private bool _loading;

    // Private pagination query (using a uniform naming convention)
    private TenantsWithPaginationQuery _tenantsQuery { get; } = new();

    protected override async Task OnInitializedAsync()
    {
        Title = L[_currentDto.GetClassDescription()];
        _accessRights = await PermissionService.GetAccessRightsAsync<TenantsAccessRights>();
    }

    // Server data loading callback
    private async Task<GridData<TenantDto>> ServerReload(GridState<TenantDto> state)
    {
        try
        {
            _loading = true;
            _tenantsQuery.Keyword = _searchString;
            var sortDefinition = state.SortDefinitions.FirstOrDefault();
            _tenantsQuery.OrderBy = sortDefinition?.SortBy ?? "Id";
            _tenantsQuery.SortDirection = (sortDefinition != null && sortDefinition.Descending)
                                      ? SortDirection.Descending.ToString()
                                      : SortDirection.Ascending.ToString();
            _tenantsQuery.PageNumber = state.Page + 1;
            _tenantsQuery.PageSize = state.PageSize;
            var result = await Mediator.Send(_tenantsQuery);
            return new GridData<TenantDto> { TotalItems = result.TotalItems, Items = result.Items };
        }
        finally
        {
            _loading = false;
        }
    }

    // Search event handler
    private async Task OnSearchTenant(string text)
    {
        _selectedItems = new HashSet<TenantDto>();
        _searchString = text;
        await _tenantGrid.ReloadServerData();
    }

    // Refresh event handler
    private async Task OnRefreshTenants()
    {
        TenantCacheKey.Refresh();
        _selectedItems = new HashSet<TenantDto>();
        _searchString = string.Empty;
        await _tenantGrid.ReloadServerData();
    }

    // Create tenant event handler
    private  Task OnCreateTenant()
    {
        return ShowEditTenantDialog(new AddEditTenantCommand(), L["Create a new Tenant"]);
    }

    // Edit tenant event handler
    private  Task OnEditTenant(TenantDto dto)
    {
        var command = Mapper.Map<AddEditTenantCommand>(dto);
        return ShowEditTenantDialog(command, L["Edit the Tenant"]);
    }

    // Delete tenant event handler
    private async Task OnDeleteTenant(TenantDto dto)
    {
        var command = new DeleteTenantCommand(new[] { dto.Id });
        var contentText = string.Format(ConstantString.DeleteConfirmationWithId, dto.Id);
        await DialogServiceHelper.ShowDeleteConfirmationDialogAsync(command, L["Delete the Tenant"], contentText, async () =>
        {
            await InvokeAsync(async () =>
            {
                await _tenantGrid.ReloadServerData();
                _selectedItems.Clear();
            });
        });
    }

    // Delete selected tenants event handler
    private async Task OnDeleteSelectedTenants()
    {
        var command = new DeleteTenantCommand(_selectedItems.Select(x => x.Id).ToArray());
        var contentText = string.Format(ConstantString.DeleteConfirmation, _selectedItems.Count);
        await DialogServiceHelper.ShowDeleteConfirmationDialogAsync(command, L["Delete Selected Tenants"], contentText, async () =>
        {
            await InvokeAsync(async () =>
            {
                await _tenantGrid.ReloadServerData();
                _selectedItems.Clear();
            });
        });
    }

    // Helper method: Show edit dialog for tenant
    private Task ShowEditTenantDialog(AddEditTenantCommand command, string title)
    {
        return DialogServiceHelper.ShowFormDialogAsync<TenantFormDialog, AddEditTenantCommand>(
            title,
            command,
            async () =>
            {
                await _tenantGrid.ReloadServerData();
                _selectedItems.Clear();
            });
    }
}
